package ms.unicorn.modellanguage.providers;

import ms.unicorn.diagram.providers.UnicornViewProvider;
import ms.unicorn.modellanguage.HintedSpecializationType;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.core.services.view.CreateChildViewOperation;
import org.eclipse.gmf.runtime.diagram.core.services.view.CreateEdgeViewOperation;
import org.eclipse.gmf.runtime.diagram.core.services.view.CreateNodeViewOperation;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.notation.Edge;
import org.eclipse.gmf.runtime.notation.Node;
import org.eclipse.gmf.runtime.notation.View;

public class ViewProvider extends UnicornViewProvider {
	
	
	protected boolean provides(CreateNodeViewOperation op) {
		return canProvide(op) ? true: super.provides(op);
	}

	protected boolean canProvide(CreateChildViewOperation op) {
		if (op.getContainerView() == null) {
			return false;
		}
		
		IElementType elementType = getSemanticElementType(op
				.getSemanticAdapter());
		
		if (elementType instanceof HintedSpecializationType) {
			HintedSpecializationType hintType = (HintedSpecializationType) elementType;
			if (hintType.getElement() != null)
				return true;
		}
		return false;
	}
	
	@Override
	protected boolean provides(CreateEdgeViewOperation op) {
		return canProvide(op) ? true: super.provides(op);
	}
	
	private View createView(IAdaptable semanticAdapter,
			View containerView, String semanticHint, int index,
			boolean persisted, PreferencesHint preferencesHint) {
		View view = null;
		IElementType elementType = getSemanticElementType(semanticAdapter);
		
		if (elementType instanceof HintedSpecializationType) {
			HintedSpecializationType hintType = (HintedSpecializationType) elementType;
			view = hintType.getElement().getEditHelperAdvice().createView(semanticAdapter, 
					containerView, semanticHint, 
					index, persisted, preferencesHint);
		}
		return view;
	}
	
	@Override
	public final Node createNode(IAdaptable semanticAdapter,
			View containerView, String semanticHint, int index,
			boolean persisted, PreferencesHint preferencesHint) {

		View nodeView = createView(semanticAdapter, containerView, semanticHint, 
				index, persisted, preferencesHint);
		if (nodeView instanceof Node)
			return (Node) nodeView;
		return super.createNode(semanticAdapter, containerView, semanticHint, index,
				persisted, preferencesHint);
	}
	
	@Override
	public Edge createEdge(IAdaptable semanticAdapter, View containerView,
			String semanticHint, int index, boolean persisted,
			PreferencesHint preferencesHint) {
		View edgeView = createView(semanticAdapter, containerView, semanticHint, 
				index, persisted, preferencesHint);
		if (edgeView instanceof Edge)
			return (Edge) edgeView;
		return super.createEdge(semanticAdapter, containerView, semanticHint, index,
				persisted, preferencesHint);
	}
}
